home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / nfs / nfswatch4.0 / RCS / nfswatch.c,v < prev    next >
Encoding:
Text File  |  1993-03-01  |  39.2 KB  |  2,228 lines

  1. head    4.0;
  2. access;
  3. symbols;
  4. locks; strict;
  5. comment    @ * @;
  6.  
  7.  
  8. 4.0
  9. date    93.03.01.19.59.00;    author davy;    state Exp;
  10. branches;
  11. next    3.13;
  12.  
  13. 3.13
  14. date    93.02.24.17.44.45;    author davy;    state Exp;
  15. branches;
  16. next    3.12;
  17.  
  18. 3.12
  19. date    93.01.20.14.52.30;    author davy;    state Exp;
  20. branches;
  21. next    3.11;
  22.  
  23. 3.11
  24. date    93.01.16.19.08.59;    author davy;    state Exp;
  25. branches;
  26. next    3.10;
  27.  
  28. 3.10
  29. date    93.01.15.22.09.20;    author davy;    state Exp;
  30. branches;
  31. next    3.9;
  32.  
  33. 3.9
  34. date    93.01.15.19.33.39;    author davy;    state Exp;
  35. branches;
  36. next    3.8;
  37.  
  38. 3.8
  39. date    93.01.15.15.43.36;    author davy;    state Exp;
  40. branches;
  41. next    3.7;
  42.  
  43. 3.7
  44. date    93.01.14.15.51.16;    author davy;    state Exp;
  45. branches;
  46. next    3.6;
  47.  
  48. 3.6
  49. date    93.01.13.21.24.19;    author davy;    state Exp;
  50. branches;
  51. next    3.5;
  52.  
  53. 3.5
  54. date    93.01.13.20.18.17;    author davy;    state Exp;
  55. branches;
  56. next    3.4;
  57.  
  58. 3.4
  59. date    93.01.13.18.59.30;    author davy;    state Exp;
  60. branches;
  61. next    3.3;
  62.  
  63. 3.3
  64. date    93.01.13.15.12.05;    author davy;    state Exp;
  65. branches;
  66. next    3.2;
  67.  
  68. 3.2
  69. date    92.07.24.18.47.57;    author mogul;    state Exp;
  70. branches;
  71. next    3.1;
  72.  
  73. 3.1
  74. date    91.01.23.16.56.19;    author mogul;    state Exp;
  75. branches;
  76. next    3.0;
  77.  
  78. 3.0
  79. date    91.01.23.08.23.11;    author davy;    state Exp;
  80. branches;
  81. next    1.5;
  82.  
  83. 1.5
  84. date    91.01.04.16.05.15;    author davy;    state Exp;
  85. branches;
  86. next    1.4;
  87.  
  88. 1.4
  89. date    91.01.04.15.54.29;    author davy;    state Exp;
  90. branches;
  91. next    1.3;
  92.  
  93. 1.3
  94. date    90.12.04.08.06.41;    author davy;    state Exp;
  95. branches;
  96. next    1.2;
  97.  
  98. 1.2
  99. date    90.08.17.15.47.29;    author davy;    state Exp;
  100. branches;
  101. next    1.1;
  102.  
  103. 1.1
  104. date    88.11.29.11.20.40;    author davy;    state Released;
  105. branches;
  106. next    ;
  107.  
  108.  
  109. desc
  110. @NFSWATCH - monitor Network File System traffic on the network.
  111. @
  112.  
  113.  
  114. 4.0
  115. log
  116. @NFSWATCH Version 4.0.
  117. @
  118. text
  119. @#ifndef lint
  120. static char *RCSid = "$Header: /home/harbor/davy/system/nfswatch/RCS/nfswatch.c,v 3.13 1993/02/24 17:44:45 davy Exp davy $";
  121. #endif
  122.  
  123. #include "os.h"
  124.  
  125. /*
  126.  * nfswatch - NFS server packet monitoring program.
  127.  *
  128.  * David A. Curry                Jeffrey C. Mogul
  129.  * Purdue University                Digital Equipment Corporation
  130.  * Engineering Computer Network            Western Research Laboratory
  131.  * 1285 Electrical Engineering Building        250 University Avenue
  132.  * West Lafayette, IN 47907-1285        Palo Alto, CA 94301
  133.  * davy@@ecn.purdue.edu                mogul@@decwrl.dec.com
  134.  *
  135.  * $Log: nfswatch.c,v $
  136.  * Revision 3.13  1993/02/24  17:44:45  davy
  137.  * Added -auth mode, changes to -proc mode, -map option, -server option.
  138.  *
  139.  * Revision 3.12  1993/01/20  14:52:30  davy
  140.  * Added -T maxtime option.
  141.  *
  142.  * Revision 3.11  1993/01/16  19:08:59  davy
  143.  * Corrected Jeff's address.
  144.  *
  145.  * Revision 3.10  1993/01/15  22:09:20  davy
  146.  * Fixed for Sun FDDI using the NIT.
  147.  *
  148.  * Revision 3.9  1993/01/15  19:33:39  davy
  149.  * Miscellaneous cleanups.
  150.  *
  151.  * Revision 3.8  1993/01/15  15:43:36  davy
  152.  * Assorted changes for porting to Solaris 2.x/SVR4.
  153.  *
  154.  * Revision 3.7  1993/01/14  15:51:16  davy
  155.  * Added FDDI code and device type calculation to NIT and SNOOP.  The FDDI
  156.  * stuff almost definitely won't work without modification on the SNOOP
  157.  * side; it still needs to be tested on the NIT side.
  158.  *
  159.  * Revision 3.6  1993/01/13  21:24:19  davy
  160.  * Assorted changes for porting to IRIX.
  161.  *
  162.  * Revision 3.5  1993/01/13  20:18:17  davy
  163.  * Put in OS-specific define scheme, and merged in Tim Hudson's code for
  164.  * SGI systems (as yet untested).
  165.  *
  166.  * Revision 3.4  1993/01/13  18:59:30  davy
  167.  * Changed sigvec calls to signal calls, for portability to other os versions.
  168.  *
  169.  * Revision 3.3  1993/01/13  15:12:05  davy
  170.  * Added background mode.
  171.  *
  172.  * Revision 3.2  1992/07/24  18:47:57  mogul
  173.  * Added FDDI support
  174.  *
  175.  * Revision 3.1  1991/01/23  16:56:19  mogul
  176.  * Black magic
  177.  *
  178.  * Revision 3.1  1991/01/23  16:56:19  mogul
  179.  * Black magic
  180.  *
  181.  * Revision 3.0  91/01/23  08:23:11  davy
  182.  * NFSWATCH Version 3.0.
  183.  * 
  184.  * Revision 1.5  91/01/04  16:05:15  davy
  185.  * Updated version number.
  186.  * 
  187.  * Revision 1.4  91/01/04  15:54:29  davy
  188.  * New features from Jeff Mogul.
  189.  * 
  190.  * Revision 1.3  90/12/04  08:06:41  davy
  191.  * Changed version number to 2.1.
  192.  * 
  193.  * Revision 1.2  90/08/17  15:47:29  davy
  194.  * NFSWATCH Version 2.0.
  195.  * 
  196.  * Revision 1.1  88/11/29  11:20:40  davy
  197.  * NFSWATCH Release 1.0
  198.  * 
  199.  */
  200. #include <sys/param.h>
  201. #include <sys/socket.h>
  202. #include <sys/ioctl.h>
  203. #include <sys/time.h>
  204. #include <net/if.h>
  205. #include <signal.h>
  206. #include <errno.h>
  207. #include <stdio.h>
  208.  
  209. #ifdef USE_DLPI
  210. #include <sys/stream.h>
  211. #include <sys/stropts.h>
  212.  
  213. #if defined(SVR4) && !defined(SUNOS5)
  214. char    *devices[] = {
  215.     "emd0", "emd1", "emd2", "emd3", "emd4",
  216.     0
  217. };
  218. #endif
  219.  
  220. #ifdef SUNOS5
  221. #include <sys/bufmod.h>
  222.  
  223. char    *devices[] = {
  224.     "le0", "le1", "le2", "le3", "le4",
  225.     "ie0", "ie1", "ie2", "ie3", "ie4",
  226.     "fddi0", "fddi1", "fddi2", "fddi3", "fddi4",
  227.     0
  228. };
  229. #endif
  230. #endif /* USE_DLPI */
  231.  
  232. #ifdef USE_NIT
  233. #include <net/nit_if.h>
  234. #include <net/nit_buf.h>
  235.  
  236. char    *devices[] = {
  237.     "le0", "le1", "le2", "le3", "le4",
  238.     "ie0", "ie1", "ie2", "ie3", "ie4",
  239.     "fddi0", "fddi1", "fddi2", "fddi3", "fddi4",
  240.     0
  241. };
  242.  
  243. #endif /* USE_NIT */
  244.  
  245. #ifdef USE_PFILT
  246. #include <net/pfilt.h>
  247.  
  248. char    *devices[] = {
  249.     "pf0", "pf1", "pf2", "pf3", "pf4", "pf5",
  250.     "pf6", "pf7", "pf8", "pf9",
  251.     0
  252. };
  253. #endif /* USE_PFILT */
  254.  
  255. #ifdef USE_SNOOP
  256. #include <net/soioctl.h>
  257. #include <net/raw.h>
  258. #include <netinet/if_ether.h>
  259.  
  260. #define ETHERHDRPAD        RAW_HDRPAD(sizeof(struct ether_header))
  261.  
  262. char    *devices[] = {
  263.     "et0", "et1", "et2", "et3", "et4",
  264.     "ec0", "ec1", "ec2", "ec3", "ec4",
  265.     "fxp0", "fxp1", "fxp2", "fxp3", "fxp4",
  266.     "enp0", "enp1", "enp2", "enp3", "enp4",
  267.     "ipg0", "ipg1", "ipg2", "ipg3", "ipg4",
  268.     0
  269. };
  270.  
  271. struct etherpacket {
  272.     struct snoopheader    snoop;
  273.     char            pad[ETHERHDRPAD];
  274.     struct ether_header    ether;
  275.     char            data[ETHERMTU];
  276. };
  277. #endif /* USE_SNOOP */
  278.  
  279. #include "nfswatch.h"
  280.  
  281. char        *pname;                /* program name        */
  282.  
  283. FILE        *logfp;                /* log file pointer    */
  284.  
  285. Counter        pkt_total = 0;            /* total packets seen    */
  286. Counter        pkt_drops = 0;            /* total packets dropped*/
  287. Counter        int_pkt_total = 0;        /* packets this interval*/
  288. Counter        int_pkt_drops = 0;        /* dropped this interval*/
  289. Counter        dst_pkt_total = 0;        /* total pkts to host    */
  290. Counter        int_dst_pkt_total = 0;        /* pkts to host this int*/
  291.  
  292. int        if_fd[MAXINTERFACES];        /* LAN device file desc    */
  293. int        if_dlt[MAXINTERFACES];        /* LAN data link type    */
  294.  
  295. int        bgflag = 0;            /* "-bg" specified    */
  296. int        srcflag = 0;            /* "-src" specified    */
  297. int        dstflag = 0;            /* "-dst" specified    */
  298. int        allflag = 0;            /* "-all" specified    */
  299. int        allintf = 0;            /* "-allif" specified    */
  300. int        logging = 0;            /* 1 when logging on    */
  301. int        learnfs = 0;            /* learn other servers    */
  302. int        do_update = 0;            /* time to update screen*/
  303. int        showwhich = 0;            /* show filesys or files*/
  304. int        serverflag = 0;            /* "-server" specified    */
  305. int        cycletime = CYCLETIME;        /* update cycle time    */
  306. int        totaltime = 0;            /* total run time    */
  307. int        truncation = 200;        /* pkt trunc len - magic*/
  308. int        sortbyusage = 0;        /* sort by usage counts    */
  309. int        nnfscounters = 0;        /* # of NFS counters    */
  310. int        nfilecounters = 0;        /* # of file counters    */
  311. int        nauthcounters = 0;        /* # of auth counters    */
  312. int        nclientcounters = 0;        /* # of client counters */
  313. int        screen_inited = 0;        /* 1 when in curses    */
  314.  
  315. struct timeval    starttime;            /* time we started    */
  316.  
  317. int        ninterfaces;            /* number of interfaces    */
  318.  
  319. u_long        thisdst = 0;            /* cached IP dst of pkt    */
  320. u_long        srcaddrs[MAXHOSTADDR];        /* src host net addrs    */
  321. u_long        dstaddrs[MAXHOSTADDR];        /* dst host net addrs    */
  322. u_long        serveraddrs[MAXHOSTADDR];    /* server host net addrs*/
  323.  
  324. char        myhost[MAXHOSTNAMELEN];        /* local host name    */
  325. char        srchost[MAXHOSTNAMELEN];    /* source host name    */
  326. char        dsthost[MAXHOSTNAMELEN];    /* destination host name*/
  327. char        serverhost[MAXHOSTNAMELEN];    /* server host name    */
  328.  
  329. char        *prompt = PROMPT;        /* prompt string    */
  330. char        *filelist = NULL;        /* list of files    */
  331. char        *logfile = LOGFILE;        /* log file name    */
  332. char        *mapfile = NULL;        /* map file name    */
  333. char        *snapshotfile = SNAPSHOTFILE;    /* snapshot file name    */
  334.  
  335. NFSCounter    nfs_counters[MAXEXPORT];    /* NFS request counters    */
  336. FileCounter    fil_counters[MAXEXPORT];    /* file request counters*/
  337. PacketCounter    pkt_counters[PKT_NCOUNTERS];    /* packet counters    */
  338. ProcCounter    prc_counters[MAXNFSPROC+2];    /* procedure counters    */
  339.                 /* extra space simplifies sort_prc_counters */
  340. int        prc_countmap[MAXNFSPROC];    /* allows sorting    */
  341. ClientCounter    clnt_counters[MAXCLIENTS];    /* per-client counters    */
  342. AuthCounter    auth_counters[MAXAUTHS];    /* per-auth counters    */
  343.  
  344. extern void finish();
  345.  
  346. #ifdef ultrix
  347. void
  348. fpe_warn()
  349. {
  350.     fprintf(stderr, "nfswatch: mystery bug encountered.\n");
  351.     finish(-1);
  352. }
  353. #endif
  354.  
  355. main(argc, argv)
  356. int argc;
  357. char **argv;
  358. {
  359.     register int i;
  360.     char *device = NULL;
  361.     extern void nfswatch();
  362.  
  363.     pname = *argv;
  364.  
  365.     /*
  366.      * Get our host name.  The default destination
  367.      * host is the one we're running on.
  368.      */
  369.     if (gethostname(myhost, sizeof(myhost)) < 0) {
  370.         error("gethostname");
  371.         finish(-1);
  372.     }
  373.  
  374.     (void) strcpy(dsthost, myhost);
  375.  
  376.     /*
  377.      * Process arguments.
  378.      */
  379.     while (--argc) {
  380.         if (**++argv != '-')
  381.             usage();
  382.  
  383.         /*
  384.          * Set destination host.
  385.          */
  386.         if (!strcmp(*argv, "-dst")) {
  387.             if (--argc <= 0)
  388.                 usage();
  389.  
  390.             (void) strcpy(dsthost, *++argv);
  391.             dstflag++;
  392.             continue;
  393.         }
  394.  
  395.         /*
  396.          * Set source host.
  397.          */
  398.         if (!strcmp(*argv, "-src")) {
  399.             if (--argc <= 0)
  400.                 usage();
  401.  
  402.             (void) strcpy(srchost, *++argv);
  403.             srcflag++;
  404.             continue;
  405.         }
  406.  
  407.         /*
  408.          * Set server host.
  409.          */
  410.         if (!strcmp(*argv, "-server")) {
  411.             if (--argc <= 0)
  412.                 usage();
  413.  
  414.             (void) strcpy(serverhost, *++argv);
  415.             serverflag++;
  416.             continue;
  417.         }
  418.  
  419.         /*
  420.          * Device to use.
  421.          */
  422.         if (!strcmp(*argv, "-dev")) {
  423.             if (--argc <= 0)
  424.                 usage();
  425.  
  426.             device = *++argv;
  427.             continue;
  428.         }
  429.  
  430.         /*
  431.          * Log file name.
  432.          */
  433.         if (!strcmp(*argv, "-lf")) {
  434.             if (--argc <= 0)
  435.                 usage();
  436.  
  437.             logfile = *++argv;
  438.             continue;
  439.         }
  440.  
  441.         /*
  442.          * Snapshot file name.
  443.          */
  444.         if (!strcmp(*argv, "-sf")) {
  445.             if (--argc <= 0)
  446.                 usage();
  447.  
  448.             snapshotfile = *++argv;
  449.             continue;
  450.         }
  451.  
  452.         /*
  453.          * List of files.
  454.          */
  455.         if (!strcmp(*argv, "-f")) {
  456.             if (--argc <= 0)
  457.                 usage();
  458.  
  459.             if (showwhich == 0)
  460.                 showwhich = SHOWINDVFILES;
  461.  
  462.             filelist = *++argv;
  463.             continue;
  464.         }
  465.  
  466.         /*
  467.          * Set map file.
  468.          */
  469.         if (!strcmp(*argv, "-map")) {
  470.             if (--argc <= 0)
  471.                 usage();
  472.  
  473.             mapfile = *++argv;
  474.             continue;
  475.         }
  476.         
  477.         /*
  478.          * Set total run time.
  479.          */
  480.         if (!strcmp(*argv, "-T")) {
  481.             if (--argc <= 0)
  482.                 usage();
  483.             
  484.             totaltime = atoi(*++argv);
  485.             continue;
  486.         }
  487.  
  488.         /*
  489.          * Change cycle time.
  490.          */
  491.         if (!strcmp(*argv, "-t")) {
  492.             if (--argc <= 0)
  493.                 usage();
  494.  
  495.             cycletime = atoi(*++argv);
  496.             continue;
  497.         }
  498.  
  499.         /*
  500.          * Show RPC authentication.
  501.          */
  502.         if (!strcmp(*argv, "-auth")) {
  503.             showwhich = SHOWAUTH;
  504.             continue;
  505.         }
  506.  
  507.         /*
  508.          * Show file systems.
  509.          */
  510.         if (!strcmp(*argv, "-fs")) {
  511.             showwhich = SHOWFILESYSTEM;
  512.             continue;
  513.         }
  514.  
  515.         /*
  516.          * Show individual files.
  517.          */
  518.         if (!strcmp(*argv, "-if")) {
  519.             showwhich = SHOWINDVFILES;
  520.             continue;
  521.         }
  522.  
  523.         /*
  524.          * Show NFS procedures
  525.          */
  526.         if (!strcmp(*argv, "-procs")) {
  527.             showwhich = SHOWNFSPROCS;
  528.             continue;
  529.         }
  530.  
  531.         /*
  532.          * Show NFS clients
  533.          */
  534.         if (!strcmp(*argv, "-clients")) {
  535.             showwhich = SHOWCLIENTS;
  536.             continue;
  537.         }
  538.  
  539.         /*
  540.          * Turn on logging.
  541.          */
  542.         if (!strcmp(*argv, "-l")) {
  543.             logging++;
  544.             continue;
  545.         }
  546.  
  547.         /*
  548.          * Run in background mode.
  549.          */
  550.         if (!strcmp(*argv, "-bg")) {
  551.             logging++;
  552.             bgflag++;
  553.             continue;
  554.         }
  555.  
  556.         /*
  557.          * Watch all traffic.
  558.          */
  559.         if (!strcmp(*argv, "-all")) {
  560.             allflag++;
  561.             continue;
  562.         }
  563.  
  564.         /*
  565.          * Use all interfaces.
  566.          */
  567.         if (!strcmp(*argv, "-allif")) {
  568.             allintf++;
  569.             continue;
  570.         }
  571.  
  572.         /*
  573.          * Sort file systems by usage, not name.
  574.          */
  575.         if (!strcmp(*argv, "-usage")) {
  576.             sortbyusage++;
  577.             continue;
  578.         }
  579.  
  580.         usage();
  581.     }
  582.  
  583.     /*
  584.      * Check what we're showing.
  585.      */
  586.     switch (showwhich) {
  587.     case 0:            /* default */
  588.         showwhich = SHOWFILESYSTEM;
  589.         break;
  590.     case SHOWINDVFILES:
  591.         if (filelist == NULL) {
  592.             (void) fprintf(stderr, "%s: must specify file list with -fi.\n", pname);
  593.             finish(-1);
  594.         }
  595.  
  596.         break;
  597.     }
  598.  
  599.     /*
  600.      * Trap signals so we can clean up.
  601.      */
  602.     (void) signal(SIGINT, finish);
  603.     (void) signal(SIGQUIT, finish);
  604.     (void) signal(SIGTERM, finish);
  605.  
  606. #ifdef sgi
  607.     /*
  608.      * Kludge to prevent coredumps when the optimizer's on?
  609.      */
  610.     (void) signal(SIGFPE, SIG_IGN);
  611. #endif
  612.  
  613. #ifdef ultrix
  614.     (void) signal(SIGFPE, fpe_warn);
  615. #endif
  616.  
  617. #ifdef USE_DLPI
  618.     /*
  619.      * Set up the data link interface provider  right away,
  620.      * since we probably need super-user permission.
  621.      */
  622.     if (allintf) {
  623.         ninterfaces = 0;
  624.         for (i=0; devices[i] != NULL; i++) {
  625.         if_fd[ninterfaces] = setup_dlpi_dev(&devices[i]);
  626.  
  627.         if (if_fd[ninterfaces] >= 0) {
  628.             if_dlt[ninterfaces] = dlpi_devtype(if_fd[ninterfaces]);
  629.             ninterfaces++;
  630.         }
  631.         }
  632.     }
  633.     else {
  634.         if_fd[0] = setup_dlpi_dev(&device);
  635.  
  636.         if (if_fd[0] < 0) {
  637.         error(device);
  638.         finish(-1);
  639.         }
  640.  
  641.         if_dlt[0] = dlpi_devtype(if_fd[0]);
  642.         ninterfaces = 1;
  643.     }
  644. #endif /* USE_DLPI */
  645.  
  646. #ifdef USE_NIT
  647.     /*
  648.      * Set up the network interface tap right away,
  649.      * since we probably need super-user permission.
  650.      */
  651.     if (allintf) {
  652.         ninterfaces = 0;
  653.         for (i=0; devices[i] != NULL; i++) {
  654.         if_fd[ninterfaces] = setup_nit_dev(&devices[i]);
  655.  
  656.         if (if_fd[ninterfaces] >= 0) {
  657.             if_dlt[ninterfaces] = nit_devtype(devices[i]);
  658.             ninterfaces++;
  659.         }
  660.         }
  661.     }
  662.     else {
  663.         if_fd[0] = setup_nit_dev(&device);
  664.  
  665.         if (if_fd[0] < 0) {
  666.         error(device);
  667.         finish(-1);
  668.         }
  669.  
  670.         if_dlt[0] = nit_devtype(device);
  671.         ninterfaces = 1;
  672.     }
  673. #endif /* USE_NIT */
  674.  
  675. #ifdef USE_PFILT
  676.     /*
  677.      * Set up the packet filter interface now,
  678.      * although we don't need super-user permission.
  679.      */
  680.     if (allintf) {
  681.         ninterfaces = 0;
  682.         for (i=0; devices[i] != NULL; i++) {
  683.         if_fd[ninterfaces] = setup_pfilt_dev(&devices[i]);
  684.  
  685.         if (if_fd[ninterfaces] >= 0) {
  686.             if_dlt[ninterfaces] = pfilt_devtype(if_fd[ninterfaces]);
  687.             ninterfaces++;
  688.         }
  689.         }
  690.     }
  691.     else {
  692.         if_fd[0] = setup_pfilt_dev(&device);
  693.  
  694.         if (if_fd[0] < 0) {
  695.         error(device);
  696.         finish(-1);
  697.         }
  698.  
  699.         if_dlt[0] = pfilt_devtype(if_fd[0]);
  700.         ninterfaces = 1;
  701.     }
  702. #endif /* USE_PFILT */
  703.  
  704. #ifdef USE_SNOOP
  705.     /*
  706.      * Set up the snoop interface right away,
  707.      * since we probably need super-user permission.
  708.      */
  709.     if (allintf) {
  710.         ninterfaces = 0;
  711.         for (i=0; devices[i] != NULL; i++) {
  712.         if_fd[ninterfaces] = setup_snoop_dev(&devices[i]);
  713.  
  714.         if (if_fd[ninterfaces] >= 0) {
  715.             if_dlt[ninterfaces] = snoop_devtype(devices[i]);
  716.             ninterfaces++;
  717.         }
  718.         }
  719.     }
  720.     else {
  721.         if_fd[0] = setup_snoop_dev(&device);
  722.  
  723.         if (if_fd[0] < 0) {
  724.         error(device);
  725.         finish(-1);
  726.         }
  727.  
  728.         if_dlt[0] = snoop_devtype(device);
  729.         ninterfaces = 1;
  730.     }
  731. #endif /* USE_SNOOP */
  732.  
  733.     if (ninterfaces < 1) {
  734.         fprintf(stderr, "%s: no valid interfaces.\n", pname);
  735.         finish(-1);
  736.     }
  737.  
  738.     /*
  739.      * Now lose super-user permission, since we
  740.      * don't need it for anything else.
  741.      */
  742. #ifdef SVR4
  743.     (void) setuid(getuid());
  744.     (void) seteuid(getuid());
  745. #else
  746.     (void) setreuid(getuid(), getuid());
  747. #endif
  748.  
  749.     /*
  750.      * Look up the network addresses of the source and
  751.      * destination hosts.
  752.      */
  753.     get_net_addrs();
  754.  
  755.     /*
  756.      * Tell the user what's going on.
  757.      */
  758.     (void) printf("NFSWATCH Version %s\n", VERSION);
  759.  
  760.     if (serverflag) {
  761.         (void) printf("Watch packets to/from %s on ", serverhost);
  762.     }
  763.     else {
  764.         (void) printf("Watch packets from %s to %s on ",
  765.                   (srcflag ? srchost : "all hosts"), dsthost);
  766.     }
  767.  
  768.     if (allintf)
  769.         (void) printf("all interfaces;\n");
  770.     else {
  771.         (void) printf("%s ", dlt_name(if_dlt[0]));
  772.         (void) printf("interface %s;\n", device);
  773.     }
  774.  
  775.     (void) printf("log to \"%s\" (logging %s);\n", logfile,
  776.         (logging ? "on" : "off"));
  777.  
  778.     if (bgflag) {
  779.         (void) printf("cycle time %d seconds;\n", cycletime);
  780.         (void) printf("running as a daemon in the background...");
  781.     }
  782.     else {
  783.         (void) printf("snapshots to \"%s\";\n", snapshotfile);
  784.         (void) printf("cycle time %d seconds...", cycletime);
  785.     }
  786.  
  787.     (void) fflush(stdout);
  788.  
  789.     /*
  790.      * No more informational output, so fork and exit if in
  791.      * background mode.
  792.      */
  793.     if (bgflag) {
  794.         int pid;
  795.  
  796.         if ((pid = fork()) < 0) {
  797.             error("fork");
  798.             finish(-1);
  799.         }
  800.  
  801.         if (pid != 0) {
  802.             printf("pid = %d\n", pid);
  803.             exit(0);
  804.         }
  805.     }
  806.  
  807.     /*
  808.      * Set up a pseudo RPC server.
  809.      */
  810.     setup_rpcxdr();
  811.  
  812.     /*
  813.      * Set up the screen.
  814.      */
  815.     if (!bgflag)
  816.         setup_screen(device);
  817.  
  818.     /*
  819.      * Set up the packet counters.  This must be done after
  820.      * setup_screen because they use the LINES variable.
  821.      */
  822.     setup_pkt_counters();
  823.     setup_nfs_counters();
  824.     setup_proc_counters();
  825.  
  826.     if (filelist)
  827.         setup_fil_counters();
  828.  
  829.     if (mapfile)
  830.         setup_map_file();
  831.  
  832.     /*
  833.      * Now label the screen.
  834.      */
  835.     if (!bgflag)
  836.         label_screen();
  837.  
  838.     /*
  839.      * Open log file if logging is on.
  840.      */
  841.     if (logging) {
  842.         if ((logfp = fopen(logfile, "a")) == NULL) {
  843.             error(logfile);
  844.             finish(-1);
  845.         }
  846.  
  847.         (void) fprintf(logfp, "#\n# startlog\n#\n");
  848.         (void) fprintf(logfp, "# NFSwatch log file\n");
  849.         (void) fprintf(logfp, "#    Packets from: %s\n",
  850.             (srcflag ? srchost : "all hosts"));
  851.         (void) fprintf(logfp, "#    Packets to:   %s\n#\n",
  852.             dsthost);
  853.     }
  854.  
  855.     /*
  856.      * Go watch packets.  Never returns.
  857.      */
  858.     nfswatch();
  859. }
  860.  
  861. /*
  862.  * nfswatch - main packet reading loop.
  863.  */
  864. void
  865. nfswatch()
  866. {
  867.     int i, cc;
  868.     char *buf;
  869.     char *malloc();
  870.     fd_set readfds;
  871.     struct timeval tv;
  872.     extern void wakeup();
  873.     struct itimerval itv;
  874.     register char *bp, *cp, *bufstop;
  875. #ifdef USE_DLPI
  876.     int tdrops[MAXINTERFACES];
  877.     struct strbuf strdata;
  878.     struct sb_hdr *hdrp;
  879.     int flags;
  880. #endif
  881. #ifdef USE_NIT
  882.     int tdrops[MAXINTERFACES];
  883.     struct nit_iftime *tstamp;
  884.     struct nit_bufhdr *hdrp;
  885.     struct nit_ifdrops *ndp;
  886. #endif
  887. #ifdef USE_PFILT
  888.     struct enstamp stamp;
  889.     int datalen;
  890. #endif
  891. #ifdef USE_SNOOP
  892.     int tdrops[MAXINTERFACES];
  893.     struct etherpacket ep;
  894.     struct rawstats rs;
  895. #endif
  896.  
  897. #ifdef USE_DLPI
  898.     /*
  899.      * Allocate a buffer so it's properly aligned for
  900.      * casting to structure types.
  901.      */
  902.     if ((buf = malloc(DLPI_CHUNKSIZE)) == NULL) {
  903.         (void) fprintf(stderr, "%s: out of memory.\n", pname);
  904.         finish(-1);
  905.     }
  906.  
  907.     strdata.len = 0;
  908.     strdata.buf = buf;
  909.     strdata.maxlen = DLPI_CHUNKSIZE;
  910. #endif
  911.  
  912. #ifdef USE_NIT
  913.     /*
  914.      * Allocate a buffer so it's properly aligned for
  915.      * casting to structure types.
  916.      */
  917.     if ((buf = malloc(NIT_CHUNKSIZE)) == NULL) {
  918.         (void) fprintf(stderr, "%s: out of memory.\n", pname);
  919.         finish(-1);
  920.     }
  921. #endif
  922.  
  923. #ifdef USE_PFILT
  924.     /*
  925.      * Allocate a buffer so it's properly aligned for
  926.      * casting to structure types.
  927.      */
  928.     if ((buf = malloc(PFILT_CHUNKSIZE)) == NULL) {
  929.         (void) fprintf(stderr, "%s: out of memory.\n", pname);
  930.         finish(-1);
  931.     }
  932. #endif
  933.  
  934.     /*
  935.      * Set up the alarm handler.
  936.      */
  937.     (void) signal(SIGALRM, wakeup);
  938.  
  939.     /*
  940.      * Set up the alarm clock.
  941.      */
  942.     (void) bzero((char *) &itv, sizeof(struct itimerval));
  943.  
  944.     itv.it_interval.tv_sec = cycletime;
  945.     itv.it_interval.tv_usec = 0;
  946.  
  947.     itv.it_value = itv.it_interval;
  948.  
  949.     (void) setitimer(ITIMER_REAL, &itv, (struct itimerval *) 0);
  950.  
  951.     /*
  952.      * Set the start time.
  953.       */
  954.     (void) gettimeofday(&starttime, (struct timezone *) 0);
  955.  
  956. #ifdef USE_DLPI
  957.     /*
  958.      * Flush the read queue of any packets that accumulated
  959.      * during setup time.
  960.      */
  961.     for (i=0; i < ninterfaces; i++) {
  962.         flush_dlpi(if_fd[i]);
  963.         tdrops[i] = 0;
  964.     }
  965.  
  966.     for (;;) {
  967.         FD_ZERO(&readfds);
  968.  
  969.         for (i=0; i < ninterfaces; i++)
  970.             FD_SET(if_fd[i], &readfds);
  971.  
  972.         /*
  973.          * See which nets have packets to read.
  974.          */
  975.         cc = select(NFDBITS, &readfds, (fd_set *) 0, (fd_set *) 0, 0);
  976.  
  977.         if ((cc < 0) && (errno != EINTR)) {
  978.             error("select");
  979.             finish(-1);
  980.         }
  981.         if (cc == 0) {
  982.             continue;
  983.         }
  984.         
  985.         /*
  986.          * For each interface...
  987.          */
  988.         for (i=0; i < ninterfaces; i++) {
  989.             /*
  990.              * Nothing to read.
  991.              */
  992.             if (!FD_ISSET(if_fd[i], &readfds))
  993.                 continue;
  994.  
  995.             /*
  996.              * Now read packets from the dlpi device.
  997.              */
  998.             flags = 0;
  999.             strdata.len = 0;
  1000.             if (getmsg(if_fd[i], NULL, &strdata, &flags) != 0)
  1001.                 continue;
  1002.  
  1003.             bufstop = buf + strdata.len;
  1004.             bp = buf;
  1005.  
  1006. #ifdef SUNOS5
  1007.             /*
  1008.              * Loop through the chunk, extracting packets.
  1009.              */
  1010.             while (bp < bufstop) {
  1011.                 cp = bp;
  1012.  
  1013.                 /*
  1014.                  * Get the nit header.
  1015.                  */
  1016.                 hdrp = (struct sb_hdr *) cp;
  1017.                 cp += sizeof(struct sb_hdr);
  1018.  
  1019.                 int_pkt_drops += hdrp->sbh_drops - tdrops[i];
  1020.                 pkt_drops += hdrp->sbh_drops - tdrops[i];
  1021.                 tdrops[i] = hdrp->sbh_drops;
  1022.  
  1023.                 /*
  1024.                  * Filter the packet.
  1025.                  */
  1026.                 if (if_dlt[i] == DLT_FDDI) {
  1027.                     pkt_filter_fddi(cp, hdrp->sbh_msglen,
  1028.                             &hdrp->sbh_timestamp);
  1029.                 }
  1030.                 else {
  1031.                     pkt_filter_ether(cp, hdrp->sbh_msglen,
  1032.                              &hdrp->sbh_timestamp);
  1033.                 }
  1034.  
  1035.                 /*
  1036.                  * Skip over this packet.
  1037.                  */
  1038.                 bp += hdrp->sbh_totlen;
  1039.             }
  1040. #else /* SUNOS5 */
  1041.             /*
  1042.              * It's just a packet, no buffering.
  1043.              */
  1044.             if (strdata.len) {
  1045.                 /*
  1046.                  * Since we're not on SunOS5, that means we
  1047.                  * don't have DLIOCRAW, so we don't have the
  1048.                  * packet frame header.  So, we need to
  1049.                  * bypass that level of filtering.
  1050.                  */
  1051.                 pkt_dispatch(bp, strdata.len, 0,
  1052.                          htons(DLPI_DEFAULTSAP), 0);
  1053.             }
  1054. #endif /* SUNOS5 */
  1055.         }
  1056. #endif /* USE_DLPI */
  1057.  
  1058. #ifdef USE_NIT
  1059.     /*
  1060.      * Flush the read queue of any packets that accumulated
  1061.      * during setup time.
  1062.      */
  1063.     for (i=0; i < ninterfaces; i++) {
  1064.         flush_nit(if_fd[i]);
  1065.         tdrops[i] = 0;
  1066.     }
  1067.  
  1068.     for (;;) {
  1069.         FD_ZERO(&readfds);
  1070.  
  1071.         for (i=0; i < ninterfaces; i++)
  1072.             FD_SET(if_fd[i], &readfds);
  1073.  
  1074.         /*
  1075.          * See which nets have packets to read.
  1076.          */
  1077.         cc = select(NFDBITS, &readfds, (fd_set *) 0, (fd_set *) 0, 0);
  1078.  
  1079.         if ((cc < 0) && (errno != EINTR)) {
  1080.             error("select");
  1081.             finish(-1);
  1082.         }
  1083.         if (cc == 0) {
  1084.             continue;
  1085.         }
  1086.         
  1087.         /*
  1088.          * For each interface...
  1089.          */
  1090.         for (i=0; i < ninterfaces; i++) {
  1091.             /*
  1092.              * Nothing to read.
  1093.              */
  1094.             if (!FD_ISSET(if_fd[i], &readfds))
  1095.                 continue;
  1096.  
  1097.             /*
  1098.              * Now read packets from the nit device.
  1099.              */
  1100.             if ((cc = read(if_fd[i], buf, NIT_CHUNKSIZE)) <= 0)
  1101.                 continue;
  1102.  
  1103.             bufstop = buf + cc;
  1104.             bp = buf;
  1105.  
  1106.             /*
  1107.              * Loop through the chunk, extracting packets.
  1108.              */
  1109.             while (bp < bufstop) {
  1110.                 cp = bp;
  1111.  
  1112.                 /*
  1113.                  * Get the nit header.
  1114.                  */
  1115.                 hdrp = (struct nit_bufhdr *) cp;
  1116.                 cp += sizeof(struct nit_bufhdr);
  1117.  
  1118.                 /*
  1119.                  * Get the time stamp.
  1120.                  */
  1121.                 tstamp = (struct nit_iftime *) cp;
  1122.                 cp += sizeof(struct nit_iftime);
  1123.  
  1124.                 /*
  1125.                  * Get the number of dropped packets.
  1126.                  */
  1127.                 ndp = (struct nit_ifdrops *) cp;
  1128.                 cp += sizeof(struct nit_ifdrops);
  1129.  
  1130.                 int_pkt_drops += ndp->nh_drops - tdrops[i];
  1131.                 pkt_drops += ndp->nh_drops - tdrops[i];
  1132.                 tdrops[i] = ndp->nh_drops;
  1133.  
  1134.                 /*
  1135.                  * Filter the packet.
  1136.                  */
  1137. #ifdef notdef
  1138.                 /*
  1139.                  * This is how it *should* be.  But the NIT
  1140.                  * device rips off the FDDI packet header
  1141.                  * and the 802.2 LLC header, and replaces
  1142.                  * them with an ethernet packet header.
  1143.                  */
  1144.                 if (if_dlt[i] == DLT_FDDI) {
  1145.                     pkt_filter_fddi(cp, hdrp->nhb_msglen,
  1146.                             &tstamp->nh_timestamp);
  1147.                 }
  1148.                 else {
  1149.                     pkt_filter_ether(cp, hdrp->nhb_msglen,
  1150.                              &tstamp->nh_timestamp);
  1151.                 }
  1152. #else
  1153.                 /*
  1154.                  * So... we just do this instead for both
  1155.                  * ethernet and FDDI.  Strange but true.
  1156.                  */
  1157.                 pkt_filter_ether(cp, hdrp->nhb_msglen,
  1158.                          &tstamp->nh_timestamp);
  1159. #endif
  1160.  
  1161.                 /*
  1162.                  * Skip over this packet.
  1163.                  */
  1164.                 bp += hdrp->nhb_totlen;
  1165.             }
  1166.         }
  1167. #endif /* USE_NIT */
  1168.  
  1169. #ifdef USE_PFILT
  1170.     /*
  1171.      * Flush the read queue of any packets that accumulated
  1172.      * during setup time.
  1173.      */
  1174.     for (i=0; i < ninterfaces; i++)
  1175.         flush_pfilt(if_fd[i]);
  1176.  
  1177.     for (;;) {
  1178.         FD_ZERO(&readfds);
  1179.  
  1180.         for (i=0; i < ninterfaces; i++)
  1181.             FD_SET(if_fd[i], &readfds);
  1182.  
  1183.         /*
  1184.          * See which interfaces have any packets to read.
  1185.          */
  1186.         cc = select(NFDBITS, &readfds, (fd_set *) 0, (fd_set *) 0, 0);
  1187.  
  1188.         if ((cc < 0) && (errno != EINTR)) {
  1189.             error("select");
  1190.             finish(-1);
  1191.         }
  1192.         if (cc == 0) {
  1193.             continue;
  1194.         }
  1195.  
  1196.         /*
  1197.          * Now read packets from the packet filter device.
  1198.          */
  1199.         for (i=0; i < ninterfaces; i++) {
  1200.             if (!FD_ISSET(if_fd[i], &readfds))
  1201.                 continue;
  1202.             
  1203.             if ((cc = read(if_fd[i], buf, PFILT_CHUNKSIZE)) < 0) {
  1204.                 lseek(if_fd[i], 0L, 0);
  1205.  
  1206.                 /*
  1207.                  * Might have read MAXINT bytes.  Try again.
  1208.                  */
  1209.                 if ((cc = read(if_fd[i], buf, PFILT_CHUNKSIZE)) < 0) {
  1210.                     error("pfilt read");
  1211.                     finish(-1);
  1212.                 }
  1213.             }
  1214.         
  1215.             bp = buf;
  1216.  
  1217.             /*
  1218.              * Loop through buffer, extracting packets.
  1219.              */
  1220.             while (cc > 0) {
  1221.                 /*
  1222.                  * Avoid alignment issues.
  1223.                  */
  1224.                 (void) bcopy(bp, &stamp, sizeof(stamp));
  1225.  
  1226.                 /*
  1227.                  * Treat entire buffer as garbage.
  1228.                  */
  1229.                 if (stamp.ens_stamplen != sizeof(stamp))
  1230.                     break;
  1231.  
  1232.                 /*
  1233.                  * Get the number of dropped packets.
  1234.                  */
  1235.                 int_pkt_drops += stamp.ens_dropped;
  1236.                 pkt_drops += stamp.ens_dropped;
  1237.  
  1238.                 /*
  1239.                  * Filter the packet.
  1240.                  */
  1241.                 datalen = stamp.ens_count;
  1242.  
  1243.                 if (datalen > truncation)
  1244.                     datalen = truncation;
  1245.  
  1246.                 if (if_dlt[i] == DLT_FDDI) {
  1247.                     /* Weird Ultrix padding */
  1248.                     pkt_filter_fddi(&(bp[sizeof(stamp) + 3]),
  1249.                             datalen,
  1250.                             &stamp.ens_tstamp);
  1251.                 }
  1252.                 else
  1253.                     pkt_filter_ether(&(bp[sizeof(stamp)]),
  1254.                              datalen,
  1255.                              &stamp.ens_tstamp);
  1256.  
  1257.                 /*
  1258.                  * Skip over this packet.
  1259.                  */
  1260.                 if (cc == (datalen + sizeof(stamp)))
  1261.                     break;
  1262.  
  1263.                 datalen = ENALIGN(datalen);
  1264.                 datalen += sizeof(stamp);
  1265.                 cc -= datalen;
  1266.                 bp += datalen;
  1267.             }
  1268.         }
  1269.  
  1270. #endif /* USE_PFILT */
  1271.  
  1272. #ifdef USE_SNOOP
  1273.     /*
  1274.      * Flush the read queue of any packets that accumulated
  1275.      * during setup time.
  1276.      */
  1277.     for (i=0; i < ninterfaces; i++) {
  1278.         flush_snoop(if_fd[i]);
  1279.         tdrops[i] = 0;
  1280.     }
  1281.  
  1282.     /*
  1283.      * Now read packets from the snooper.
  1284.      */
  1285.     for (;;) {
  1286.         int dropped;
  1287.  
  1288.         FD_ZERO(&readfds);
  1289.  
  1290.         for (i=0; i < ninterfaces; i++)
  1291.             FD_SET(if_fd[i], &readfds);
  1292.  
  1293.         /*
  1294.          * See which nets have packets to read.
  1295.          */
  1296.         cc = select(NFDBITS, &readfds, (fd_set *) 0, (fd_set *) 0, 0);
  1297.  
  1298.         if ((cc < 0) && (errno != EINTR)) {
  1299.             error("select");
  1300.             finish(-1);
  1301.         }
  1302.         if (cc == 0) {
  1303.             continue;
  1304.         }
  1305.         
  1306.         /*
  1307.          * For each interface...
  1308.          */
  1309.         for (i=0; i < ninterfaces; i++) {
  1310.             /*
  1311.              * Nothing to read.
  1312.              */
  1313.             if (!FD_ISSET(if_fd[i], &readfds))
  1314.                 continue;
  1315.  
  1316.             /*
  1317.              * Now read packets from the nit device.
  1318.              */
  1319.             if ((cc = read(if_fd[i], &ep, sizeof(ep))) <= 0)
  1320.                 continue;
  1321.  
  1322.             if (do_update) {
  1323.                 /*
  1324.                  * Get the number of dropped packets.
  1325.                  */
  1326.                 if (ioctl(if_fd[i], SIOCRAWSTATS, &rs) == 0) {
  1327.                     dropped = rs.rs_snoop.ss_ifdrops +
  1328.                           rs.rs_snoop.ss_sbdrops;
  1329.  
  1330.                     int_pkt_drops += dropped - tdrops[i];
  1331.                     pkt_drops += dropped - tdrops[i];
  1332.                     tdrops[i] = dropped;
  1333.                 }
  1334.             }
  1335.  
  1336.             /*
  1337.              * Filter the packet.
  1338.              */
  1339.             if (if_dlt[i] == DLT_FDDI) {
  1340.                 /*
  1341.                  * This probably won't work.
  1342.                  */
  1343.                 pkt_filter_fddi(&ep.ether,
  1344.                         ep.snoop.snoop_packetlen,
  1345.                         &ep.snoop.snoop_timestamp);
  1346.             }
  1347.             else {
  1348.                 pkt_filter_ether(&ep.ether,
  1349.                          ep.snoop.snoop_packetlen,
  1350.                          &ep.snoop.snoop_timestamp);
  1351.             }
  1352.         }
  1353. #endif /* USE_SNOOP */
  1354.  
  1355.         tv.tv_sec = 0;
  1356.         tv.tv_usec = 0;
  1357.         FD_ZERO(&readfds);
  1358.         FD_SET(0, &readfds);
  1359.  
  1360.         /*
  1361.          * See if a command has been typed.
  1362.          */
  1363.         if (!bgflag) {
  1364.             cc = select(NFDBITS, &readfds, (fd_set *) 0,
  1365.                     (fd_set *) 0, &tv);
  1366.  
  1367.             if ((cc > 0) && FD_ISSET(0, &readfds))
  1368.                 command();
  1369.         }
  1370.     }
  1371. }
  1372. @
  1373.  
  1374.  
  1375. 3.13
  1376. log
  1377. @Added -auth mode, changes to -proc mode, -map option, -server option.
  1378. @
  1379. text
  1380. @d2 1
  1381. a2 1
  1382. static char *RCSid = "$Header: /home/harbor/davy/system/nfswatch/RCS/nfswatch.c,v 3.12 1993/01/20 14:52:30 davy Exp davy $";
  1383. d18 3
  1384. @
  1385.  
  1386.  
  1387. 3.12
  1388. log
  1389. @Added -T maxtime option.
  1390. @
  1391. text
  1392. @d2 1
  1393. a2 1
  1394. static char *RCSid = "$Header: /home/harbor/davy/system/nfswatch/RCS/nfswatch.c,v 3.11 1993/01/16 19:08:59 davy Exp davy $";
  1395. d18 3
  1396. d183 1
  1397. d190 1
  1398. d201 1
  1399. d206 1
  1400. d211 1
  1401. d221 1
  1402. d287 12
  1403. d346 11
  1404. d379 8
  1405. a637 2
  1406.     (void) printf("Watch packets from %s to %s on ",
  1407.         (srcflag ? srchost : "all hosts"), dsthost);
  1408. d639 8
  1409. d708 3
  1410. d762 1
  1411. d905 8
  1412. a912 4
  1413.                 if (if_dlt[i] == DLT_FDDI)
  1414.                     pkt_filter_fddi(cp, hdrp->sbh_msglen);
  1415.                 else
  1416.                     pkt_filter_ether(cp, hdrp->sbh_msglen);
  1417. d931 1
  1418. a931 1
  1419.                          htons(DLPI_DEFAULTSAP));
  1420. d998 6
  1421. d1023 8
  1422. a1030 4
  1423.                 if (if_dlt[i] == DLT_FDDI)
  1424.                     pkt_filter_fddi(cp, hdrp->nhb_msglen);
  1425.                 else
  1426.                     pkt_filter_ether(cp, hdrp->nhb_msglen);
  1427. d1036 2
  1428. a1037 1
  1429.                 pkt_filter_ether(cp, hdrp->nhb_msglen);
  1430. d1128 2
  1431. a1129 1
  1432.                             datalen);
  1433. d1133 2
  1434. a1134 1
  1435.                             datalen);
  1436. d1223 2
  1437. a1224 1
  1438.                         ep.snoop.snoop_packetlen);
  1439. d1228 2
  1440. a1229 1
  1441.                          ep.snoop.snoop_packetlen);
  1442. @
  1443.  
  1444.  
  1445. 3.11
  1446. log
  1447. @Corrected Jeff's address.
  1448. @
  1449. text
  1450. @d2 1
  1451. a2 1
  1452. static char *RCSid = "$Header: /home/harbor/davy/system/nfswatch/RCS/nfswatch.c,v 3.10 1993/01/15 22:09:20 davy Exp davy $";
  1453. d18 3
  1454. d181 1
  1455. d321 11
  1456. @
  1457.  
  1458.  
  1459. 3.10
  1460. log
  1461. @Fixed for Sun FDDI using the NIT.
  1462. @
  1463. text
  1464. @d2 1
  1465. a2 1
  1466. static char *RCSid = "$Header: /home/harbor/davy/system/nfswatch/RCS/nfswatch.c,v 3.9 1993/01/15 19:33:39 davy Exp davy $";
  1467. d13 1
  1468. a13 1
  1469.  * 1285 Electrical Engineering Building        100 Hamilton Avenue
  1470. d18 3
  1471. @
  1472.  
  1473.  
  1474. 3.9
  1475. log
  1476. @Miscellaneous cleanups.
  1477. @
  1478. text
  1479. @d2 1
  1480. a2 1
  1481. static char *RCSid = "$Header: /home/harbor/davy/system/nfswatch/RCS/nfswatch.c,v 3.8 1993/01/15 15:43:36 davy Exp davy $";
  1482. d18 3
  1483. d938 7
  1484. d949 7
  1485. @
  1486.  
  1487.  
  1488. 3.8
  1489. log
  1490. @Assorted changes for porting to Solaris 2.x/SVR4.
  1491. @
  1492. text
  1493. @d2 1
  1494. a2 1
  1495. static char *RCSid = "$Header: /home/harbor/davy/system/nfswatch/RCS/nfswatch.c,v 3.7 1993/01/14 15:51:16 davy Exp davy $";
  1496. d5 2
  1497. d11 5
  1498. a15 5
  1499.  * SRI International                Digital Equipment Corporation
  1500.  * 333 Ravenswood Avenue            Western Research Laboratory
  1501.  * Menlo Park, CA 94025                100 Hamilton Avenue
  1502.  * davy@@erg.sri.com                Palo Alto, CA 94301
  1503.  *                        mogul@@decwrl.dec.com
  1504. d18 3
  1505. a75 2
  1506. #include "os.h"
  1507.  
  1508. d80 1
  1509. a80 1
  1510. # if defined(SVR4) && !defined(SUNOS5)
  1511. d85 1
  1512. a85 1
  1513. # endif /* SVR4 && !SUNOS5 */
  1514. d87 2
  1515. a88 2
  1516. # ifdef SUNOS5
  1517. # include <sys/bufmod.h>
  1518. d96 1
  1519. a96 1
  1520. # endif /* SUNOS5 */
  1521. a145 1
  1522.  
  1523. d213 1
  1524. a213 1
  1525. #endif /* ultrix */
  1526. d433 1
  1527. a433 1
  1528. #endif /* ultrix */
  1529. d689 1
  1530. a689 2
  1531. #endif /* USE_DLPI */
  1532.  
  1533. d694 1
  1534. a694 2
  1535. #endif /* USE_NIT */
  1536.  
  1537. d698 1
  1538. a698 2
  1539. #endif /* USE_PFILT */
  1540.  
  1541. d703 1
  1542. a703 1
  1543. #endif /* USE_SNOOP */
  1544. d718 1
  1545. a718 1
  1546. #endif /* USE_DLPI */
  1547. d729 1
  1548. a729 1
  1549. #endif /* USE_NIT */
  1550. d740 1
  1551. a740 1
  1552. #endif /* USE_PFILT */
  1553. d844 1
  1554. a844 1
  1555. #else
  1556. @
  1557.  
  1558.  
  1559. 3.7
  1560. log
  1561. @Added FDDI code and device type calculation to NIT and SNOOP.  The FDDI
  1562. stuff almost definitely won't work without modification on the SNOOP
  1563. side; it still needs to be tested on the NIT side.
  1564. @
  1565. text
  1566. @d2 1
  1567. a2 1
  1568. static char *RCSid = "$Header: /home/harbor/davy/system/nfswatch/RCS/nfswatch.c,v 3.6 1993/01/13 21:24:19 davy Exp davy $";
  1569. d16 5
  1570. d73 23
  1571. d101 3
  1572. a103 3
  1573.     "le0", "le1", "le2", "le3",
  1574.     "ie0", "ie1", "ie2", "ie3",
  1575.     "fddi0", "fddi1", "fddi2", "fddi3",
  1576. d127 5
  1577. a131 5
  1578.     "et0", "et1", "et2", "et3",
  1579.     "ec0", "ec1", "ec2", "ec3",
  1580.     "fxp0", "fxp1", "fxp2", "fxp3",
  1581.     "enp0", "enp1", "enp2", "enp3",
  1582.     "ipg0", "ipg1", "ipg2", "ipg3",
  1583. d143 1
  1584. d202 2
  1585. a207 2
  1586.     extern void finish();
  1587.  
  1588. d219 1
  1589. a219 1
  1590.     extern void finish(), nfswatch();
  1591. d420 1
  1592. d433 29
  1593. d482 1
  1594. a482 1
  1595.         perror(device);
  1596. d511 1
  1597. a511 1
  1598.         perror(device);
  1599. d540 1
  1600. a540 1
  1601.         perror(device);
  1602. d558 4
  1603. d563 1
  1604. d607 1
  1605. a607 1
  1606.             perror("fork");
  1607. d682 7
  1608. d706 15
  1609. d762 7
  1610. d770 92
  1611. a861 1
  1612.     (void) gettimeofday(&starttime, (struct timezone *) 0);
  1613. @
  1614.  
  1615.  
  1616. 3.6
  1617. log
  1618. @Assorted changes for porting to IRIX.
  1619. @
  1620. text
  1621. @d2 1
  1622. a2 1
  1623. static char *RCSid = "$Header: /home/harbor/davy/system/nfswatch/RCS/nfswatch.c,v 3.5 1993/01/13 20:18:17 davy Exp davy $";
  1624. d16 3
  1625. d73 3
  1626. a75 2
  1627.     "le0", "ie0", "le1", "ie1", "le2", "ie2",
  1628.     "le3", "ie3", "le4", "ie4",
  1629. d78 1
  1630. d96 1
  1631. a96 1
  1632. #define ETHERHDRPAD    RAW_HDRPAD(sizeof(struct ether_header))
  1633. d99 5
  1634. a103 2
  1635.     "et0", "ec0", "fxp0", "enp0",
  1636.     "et1", "ec1", "fxp1", "enp1",
  1637. d409 3
  1638. a411 3
  1639.         ninterfaces = 0;
  1640.         for (i=0; devices[i] != NULL; i++) {
  1641.             if_fd[ninterfaces] = setup_nit_dev(&devices[i]);
  1642. d413 3
  1643. a415 2
  1644.             if (if_fd[ninterfaces] >= 0)
  1645.                 ninterfaces++;
  1646. d417 1
  1647. d420 1
  1648. a420 1
  1649.         if_fd[0] = setup_nit_dev(&device);
  1650. d422 4
  1651. a425 4
  1652.         if (if_fd[0] < 0) {
  1653.             perror(device);
  1654.             finish(-1);
  1655.         }
  1656. d427 2
  1657. a428 1
  1658.         ninterfaces = 1;
  1659. d449 1
  1660. a449 1
  1661.         if_fd[0] = setup_pfilt_dev(&device);
  1662. d451 4
  1663. a454 4
  1664.         if (if_fd[0] < 0) {
  1665.             perror(device);
  1666.             finish(-1);
  1667.         }
  1668. d456 2
  1669. a457 3
  1670.         if_dlt[0] = pfilt_devtype(if_fd[0]);
  1671.         
  1672.         ninterfaces = 1;
  1673. d467 3
  1674. a469 3
  1675.         ninterfaces = 0;
  1676.         for (i=0; devices[i] != NULL; i++) {
  1677.             if_fd[ninterfaces] = setup_snoop_dev(&devices[i]);
  1678. d471 3
  1679. a473 2
  1680.             if (if_fd[ninterfaces] >= 0)
  1681.                 ninterfaces++;
  1682. d475 1
  1683. d478 1
  1684. a478 1
  1685.         if_fd[0] = setup_snoop_dev(&device);
  1686. d480 4
  1687. a483 4
  1688.         if (if_fd[0] < 0) {
  1689.             perror(device);
  1690.             finish(-1);
  1691.         }
  1692. d485 2
  1693. a486 1
  1694.         ninterfaces = 1;
  1695. d752 4
  1696. a755 1
  1697.                 pkt_filter_ether(cp, hdrp->nhb_msglen);
  1698. d933 11
  1699. a943 1
  1700.             pkt_filter_ether(&ep.ether, ep.snoop.snoop_packetlen);
  1701. @
  1702.  
  1703.  
  1704. 3.5
  1705. log
  1706. @Put in OS-specific define scheme, and merged in Tim Hudson's code for
  1707. SGI systems (as yet untested).
  1708. @
  1709. text
  1710. @d2 1
  1711. a2 1
  1712. static char *RCSid = "$Header: /home/harbor/davy/system/nfswatch/RCS/nfswatch.c,v 3.4 1993/01/13 18:59:30 davy Exp davy $";
  1713. d16 4
  1714. d93 6
  1715. d104 1
  1716. a104 1
  1717. }
  1718. d384 7
  1719. d622 1
  1720. d631 1
  1721. d633 1
  1722. d635 10
  1723. d783 1
  1724. a783 1
  1725.             if ((cc = read(if_fd[i], buf, NIT_CHUNKSIZE)) < 0) {
  1726. d789 1
  1727. a789 1
  1728.                 if ((cc = read(if_fd[i], buf, NIT_CHUNKSIZE)) < 0) {
  1729. d908 4
  1730. a911 3
  1731.                 int_pkt_drops += dropped - tdrops[i];
  1732.                 pkt_drops += dropped - tdrops[i];
  1733.                 tdrops[i] = dropped;
  1734. @
  1735.  
  1736.  
  1737. 3.4
  1738. log
  1739. @Changed sigvec calls to signal calls, for portability to other os versions.
  1740. @
  1741. text
  1742. @d2 1
  1743. a2 1
  1744. static char *RCSid = "$Header: /home/harbor/davy/system/nfswatch/RCS/nfswatch.c,v 3.3 1993/01/13 15:12:05 davy Exp davy $";
  1745. d16 3
  1746. d59 3
  1747. a61 1
  1748. #ifdef sun
  1749. a64 2
  1750. #define USE_NIT
  1751.  
  1752. d70 1
  1753. a70 1
  1754. #endif /* sun */
  1755. d72 1
  1756. a72 1
  1757. #ifdef ultrix
  1758. a74 2
  1759. #define USE_PFILT
  1760.  
  1761. d80 1
  1762. a80 1
  1763. #endif /* ultrix */
  1764. d82 15
  1765. d434 26
  1766. d599 6
  1767. d819 70
  1768. @
  1769.  
  1770.  
  1771. 3.3
  1772. log
  1773. @Added background mode.
  1774. @
  1775. text
  1776. @d2 1
  1777. a2 1
  1778. static char *RCSid = "$Header: /home/harbor/davy/system/nfswatch/RCS/nfswatch.c,v 3.2 1992/07/24 18:47:57 mogul Exp davy $";
  1779. d16 3
  1780. a154 1
  1781.     struct sigvec sv;
  1782. d355 2
  1783. a356 2
  1784.     sv.sv_handler = finish;
  1785.     sv.sv_mask = sv.sv_flags = 0;
  1786. a357 3
  1787.     (void) sigvec(SIGINT, &sv, (struct sigvec *) 0);
  1788.     (void) sigvec(SIGQUIT, &sv, (struct sigvec *) 0);
  1789.  
  1790. d359 1
  1791. a359 2
  1792.     sv.sv_handler = fpe_warn;
  1793.     (void) sigvec(SIGFPE, &sv, (struct sigvec *) 0);
  1794. a541 1
  1795.     struct sigvec sv;
  1796. d569 1
  1797. a569 4
  1798.     sv.sv_handler = wakeup;
  1799.     sv.sv_mask = sv.sv_flags = 0;
  1800.  
  1801.     (void) sigvec(SIGALRM, &sv, (struct sigvec *) 0);
  1802. @
  1803.  
  1804.  
  1805. 3.2
  1806. log
  1807. @Added FDDI support
  1808. @
  1809. text
  1810. @d2 1
  1811. a2 1
  1812. static char *RCSid = "$Header: /tmp_mnt/r/jove/jove_u2/mogul/code/nfswatch/RCS/nfswatch.c,v 3.1 1991/01/23 16:56:19 mogul Exp $";
  1813. d16 3
  1814. d94 1
  1815. d299 9
  1816. d453 10
  1817. a462 2
  1818.     (void) printf("snapshots to \"%s\";\n", snapshotfile);
  1819.     (void) printf("cycle time %d seconds...", cycletime);
  1820. d466 18
  1821. d491 2
  1822. a492 1
  1823.     setup_screen(device);
  1824. d508 2
  1825. a509 1
  1826.     label_screen();
  1827. d786 3
  1828. a788 1
  1829.         cc = select(NFDBITS, &readfds, (fd_set *) 0, (fd_set *) 0, &tv);
  1830. d790 3
  1831. a792 2
  1832.         if ((cc > 0) && FD_ISSET(0, &readfds))
  1833.             command();
  1834. @
  1835.  
  1836.  
  1837. 3.1
  1838. log
  1839. @Black magic
  1840. @
  1841. text
  1842. @d2 1
  1843. a2 1
  1844. static char *RCSid = "$Header: nfswatch.c,v 3.0 91/01/23 08:23:11 mogul Locked $";
  1845. d15 7
  1846. a21 1
  1847.  * $Log:    nfswatch.c,v $
  1848. d88 2
  1849. a89 1
  1850. int        if_fd[MAXINTERFACES];        /* nit device file desc    */
  1851. d383 7
  1852. a389 6
  1853.         ninterfaces = 0;
  1854.         for (i=0; devices[i] != NULL; i++) {
  1855.             if_fd[ninterfaces] = setup_pfilt_dev(&devices[i]);
  1856.  
  1857.             if (if_fd[ninterfaces] >= 0)
  1858.                 ninterfaces++;
  1859. d391 1
  1860. d401 2
  1861. d433 2
  1862. a434 1
  1863.     else
  1864. d436 1
  1865. d626 1
  1866. a626 1
  1867.                 pkt_filter(cp, hdrp->nhb_msglen);
  1868. d713 8
  1869. a720 1
  1870.                 pkt_filter(&(bp[sizeof(stamp)]), datalen);
  1871. @
  1872.  
  1873.  
  1874. 3.0
  1875. log
  1876. @NFSWATCH Version 3.0.
  1877. @
  1878. text
  1879. @d2 1
  1880. a2 1
  1881. static char *RCSid = "$Header: /tmp_mnt/net/sparky.a/davy/system/nfswatch/RCS/nfswatch.c,v 1.5 91/01/04 16:05:15 davy Exp Locker: davy $";
  1882. d16 3
  1883. d126 8
  1884. a133 1
  1885. void        fpe_warn();
  1886. a730 11
  1887.  
  1888. #ifdef ultrix
  1889. void
  1890. fpe_warn()
  1891. {
  1892.     extern void finish();
  1893.  
  1894.     fprintf(stderr, "nfswatch: mystery bug encountered.\n");
  1895.     finish(-1);
  1896. }
  1897. #endif /* ultrix */
  1898. @
  1899.  
  1900.  
  1901. 1.5
  1902. log
  1903. @Updated version number.
  1904. @
  1905. text
  1906. @d2 1
  1907. a2 1
  1908. static char *RCSid = "$Header: /tmp_mnt/net/sparky.a/davy/system/nfswatch/RCS/nfswatch.c,v 1.4 91/01/04 15:54:29 davy Exp Locker: davy $";
  1909. d8 6
  1910. a13 5
  1911.  * David A. Curry
  1912.  * SRI International
  1913.  * 333 Ravenswood Avenue
  1914.  * Menlo Park, CA 94025
  1915.  * davy@@itstd.sri.com
  1916. d16 3
  1917. d46 6
  1918. d58 6
  1919. d79 2
  1920. a80 1
  1921. int        if_fd = -1;            /* nit device file desc    */
  1922. d84 1
  1923. d99 2
  1924. d122 4
  1925. d130 1
  1926. d286 8
  1927. d329 5
  1928. d339 19
  1929. a357 1
  1930.     setup_nit_dev(device);
  1931. d365 19
  1932. a383 1
  1933.     setup_pfilt_dev(device);
  1934. d386 5
  1935. d406 2
  1936. a407 2
  1937.     (void) printf("NFSWATCH Version 2.5; January, 1991\n");
  1938.     (void) printf("Watch packets from %s to %s;\n",
  1939. d409 6
  1940. d429 1
  1941. a429 1
  1942.     setup_screen();
  1943. d476 1
  1944. a476 1
  1945.     int cc;
  1946. d486 1
  1947. d535 4
  1948. a538 1
  1949.     flush_nit();
  1950. d540 2
  1951. a541 6
  1952.     /*
  1953.      * Now read packets from the nit device.
  1954.      */
  1955.     while ((cc = read(if_fd, buf, NIT_CHUNKSIZE)) >= 0) {
  1956.         bufstop = buf + cc;
  1957.         bp = buf;
  1958. d543 3
  1959. d547 1
  1960. a547 1
  1961.          * Loop through the chunk, extracting packets.
  1962. d549 1
  1963. a549 2
  1964.         while (bp < bufstop) {
  1965.             cp = bp;
  1966. d551 12
  1967. d564 1
  1968. a564 1
  1969.              * Get the nit header.
  1970. d566 2
  1971. a567 2
  1972.             hdrp = (struct nit_bufhdr *) cp;
  1973.             cp += sizeof(struct nit_bufhdr);
  1974. d570 1
  1975. a570 1
  1976.              * Get the number of dropped packets.
  1977. d572 2
  1978. a573 2
  1979.             ndp = (struct nit_ifdrops *) cp;
  1980.             cp += sizeof(struct nit_ifdrops);
  1981. d575 2
  1982. a576 2
  1983.             int_pkt_drops += ndp->nh_drops - pkt_drops;
  1984.             pkt_drops = ndp->nh_drops;
  1985. d579 1
  1986. a579 1
  1987.              * Filter the packet.
  1988. d581 2
  1989. a582 1
  1990.             pkt_filter(cp, hdrp->nhb_msglen);
  1991. d584 26
  1992. a609 4
  1993.             /*
  1994.              * Skip over this packet.
  1995.              */
  1996.             bp += hdrp->nhb_totlen;
  1997. d618 2
  1998. a619 1
  1999.     flush_pfilt();
  2000. a620 3
  2001.     /*
  2002.      * Now read packets from the packet filter device.
  2003.      */
  2004. d622 1
  2005. a622 2
  2006.         if ((cc = read(if_fd, buf, NIT_CHUNKSIZE)) < 0) {
  2007.             lseek(if_fd, 0L, 0);
  2008. d624 11
  2009. a634 7
  2010.             /*
  2011.             * Might have read MAXINT bytes.  Try again.
  2012.             */
  2013.             if ((cc = read(if_fd, buf, NIT_CHUNKSIZE)) < 0) {
  2014.                 error("pfilt read");
  2015.                 finish(-1);
  2016.             }
  2017. d636 3
  2018. a638 2
  2019.         
  2020.         bp = buf;
  2021. d641 1
  2022. a641 1
  2023.          * Loop through buffer, extracting packets.
  2024. d643 6
  2025. a648 5
  2026.         while (cc > 0) {
  2027.             /*
  2028.              * Avoid alignment issues.
  2029.              */
  2030.             (void) bcopy(bp, &stamp, sizeof(stamp));
  2031. d650 10
  2032. a659 5
  2033.             /*
  2034.              * Treat entire buffer as garbage.
  2035.              */
  2036.             if (stamp.ens_stamplen != sizeof(stamp))
  2037.                 break;
  2038. d662 1
  2039. a662 1
  2040.              * Get the number of dropped packets.
  2041. d664 5
  2042. a668 2
  2043.             int_pkt_drops += stamp.ens_dropped;
  2044.             pkt_drops += stamp.ens_dropped;
  2045. d670 5
  2046. a674 4
  2047.             /*
  2048.              * Filter the packet.
  2049.              */
  2050.             datalen = stamp.ens_count;
  2051. d676 5
  2052. a680 2
  2053.             if (datalen > truncation)
  2054.                 datalen = truncation;
  2055. d682 4
  2056. a685 1
  2057.             pkt_filter(&(bp[sizeof(stamp)]), datalen);
  2058. d687 2
  2059. a688 5
  2060.             /*
  2061.              * Skip over this packet.
  2062.              */
  2063.             if (cc == (datalen + sizeof(stamp)))
  2064.                 break;
  2065. d690 1
  2066. a690 6
  2067.             datalen = ENALIGN(datalen);
  2068.             datalen += sizeof(stamp);
  2069.             cc -= datalen;
  2070.             bp += datalen;
  2071.         }
  2072. #endif /* USE_PFILT */
  2073. d692 10
  2074. a701 14
  2075.         /*
  2076.          * Do a screen update if necessary.
  2077.          * Clear the interval counters and
  2078.          * reset the timer.
  2079.          */
  2080.         if (do_update) {
  2081.             /*
  2082.              * Re-sort and re-do the labels.
  2083.              */
  2084.             if (sortbyusage) {
  2085.                 sort_nfs_counters();
  2086.                 sort_prc_counters();
  2087.                 sort_clnt_counters();
  2088.                 label_screen();
  2089. d703 1
  2090. d705 1
  2091. a705 1
  2092.             update_screen();
  2093. a706 11
  2094.             if (logging)
  2095.                 update_logfile();
  2096.  
  2097.             clear_vars();
  2098.  
  2099.             do_update = 0;
  2100.         }
  2101.  
  2102.         /*
  2103.          * Set up to see if there's input.
  2104.          */
  2105. d713 1
  2106. a713 2
  2107.          * See if the user typed a command,
  2108.          * and process it if he did.
  2109. d720 1
  2110. d722 7
  2111. a728 5
  2112. #ifdef USE_NIT
  2113.     /*
  2114.      * Should never get here.
  2115.      */
  2116.     error("nit read");
  2117. a729 1
  2118. #endif /* USE_NIT */
  2119. d731 1
  2120. @
  2121.  
  2122.  
  2123. 1.4
  2124. log
  2125. @New features from Jeff Mogul.
  2126. @
  2127. text
  2128. @d2 1
  2129. a2 1
  2130. static char *RCSid = "$Header: nfswatch.c,v 1.5 91/01/04 14:12:09 mogul Exp $";
  2131. d15 3
  2132. d327 1
  2133. a327 1
  2134.     (void) printf("NFSWATCH Version 2.1; December, 1990\n");
  2135. @
  2136.  
  2137.  
  2138. 1.3
  2139. log
  2140. @Changed version number to 2.1.
  2141. @
  2142. text
  2143. @d2 1
  2144. a2 1
  2145. static char *RCSid = "$Header: /tmp_mnt/net/sparky.a/davy/progs/nfswatch/RCS/nfswatch.c,v 1.2 90/08/17 15:47:29 davy Exp Locker: davy $";
  2146. d15 3
  2147. d73 1
  2148. d94 4
  2149. d226 16
  2150. d349 1
  2151. d568 2
  2152. @
  2153.  
  2154.  
  2155. 1.2
  2156. log
  2157. @NFSWATCH Version 2.0.
  2158. @
  2159. text
  2160. @d2 1
  2161. a2 1
  2162. static char *RCSid = "$Header: /tmp_mnt/net/sparky.a/davy/system/nfswatch/RCS/nfswatch.c,v 1.1 88/11/29 11:20:40 davy Released Locker: davy $";
  2163. d15 3
  2164. d300 1
  2165. a300 1
  2166.     (void) printf("NFSWATCH Version 2.0; August, 1990\n");
  2167. @
  2168.  
  2169.  
  2170. 1.1
  2171. log
  2172. @NFSWATCH Release 1.0
  2173. @
  2174. text
  2175. @d2 1
  2176. a2 1
  2177. static char *RCSid = "$Header$";
  2178. d9 4
  2179. a12 5
  2180.  * Research Institute for Advanced Computer Science
  2181.  * Mail Stop 230-5
  2182.  * NASA Ames Research Center
  2183.  * Moffett Field, CA 94035
  2184.  * davy@@riacs.edu
  2185. d14 4
  2186. a17 1
  2187.  * $Log$
  2188. d28 1
  2189. d32 9
  2190. d57 1
  2191. d59 2
  2192. a60 1
  2193. int        doupdate = 0;            /* time to update screen*/
  2194. d63 2
  2195. d71 1
  2196. d222 16
  2197. d266 1
  2198. d272 1
  2199. d274 1
  2200. d276 7
  2201. d297 1
  2202. d368 2
  2203. d372 1
  2204. a372 1
  2205.     register char *bp, *cp, *bufstop;
  2206. d374 5
  2207. d409 6
  2208. a420 5
  2209.      * Set the start time.
  2210.      */
  2211.     (void) gettimeofday(&starttime, (struct timezone *) 0);
  2212.  
  2213.     /*
  2214. d458 24
  2215. d483 2
  2216. d486 44
  2217. d534 9
  2218. a542 1
  2219.         if (doupdate) {
  2220. d550 1
  2221. a550 1
  2222.             doupdate = 0;
  2223. d571 1
  2224. d577 1
  2225. a578 1
  2226.  
  2227. @
  2228.